package cn.uestc.labhms.modules.hms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.uestc.labhms.modules.hms.dao.BaseInfoDao;
import cn.uestc.labhms.modules.hms.dao.HmsChiEngDao;
import cn.uestc.labhms.modules.hms.dao.XlsxDao;
import cn.uestc.labhms.modules.hms.entity.BaseInfoEntity;
import cn.uestc.labhms.modules.hms.entity.HmsChiEngEntity;
import cn.uestc.labhms.modules.hms.entity.Vo.TimeLineVo;
import cn.uestc.labhms.modules.hms.exception.HMSException;
import cn.uestc.labhms.modules.hms.param.ConstParam;
import cn.uestc.labhms.modules.hms.service.TimeLineService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * @author Mu.tz
 */
@Service
@Slf4j
public class TimeLineServiceImpl implements TimeLineService {
    private final HmsChiEngDao hmsChiEngDao;
    private final XlsxDao xlsxDao;
    private final BaseInfoDao baseInfoDao;

    @Autowired
    public TimeLineServiceImpl(HmsChiEngDao hmsChiEngDao, XlsxDao xlsxDao, BaseInfoDao baseInfoDao) {
        this.hmsChiEngDao = hmsChiEngDao;
        this.xlsxDao = xlsxDao;
        this.baseInfoDao = baseInfoDao;
    }

    @Override
    public List<TimeLineVo> getTimeLine(Integer patientId) {
        Integer cnt = baseInfoDao.selectCount(new QueryWrapper<BaseInfoEntity>()
                .eq("patient_id", patientId));
        if (cnt == null || cnt == 0 || ObjectUtils.isEmpty(patientId)) {
            throw new HMSException("不存在此病人");
        }
        // 获取具有patient_id的记录
        List<HmsChiEngEntity> containsPatientId = hmsChiEngDao.selectList(new QueryWrapper<HmsChiEngEntity>()
                .eq("eng_field", "patient_id"));
        // 获取具有日期字段的记录
        List<HmsChiEngEntity> containsDate = hmsChiEngDao.selectList(new QueryWrapper<HmsChiEngEntity>()
                .like("eng_field", "date"));
        // 过滤出同时具有patient_id和日期字段的记录
        Set<HmsChiEngEntity> records = new HashSet<>(containsPatientId.size());
        for (HmsChiEngEntity chiEngEntity : containsPatientId) {
            for (HmsChiEngEntity hmsChiEngEntity : containsDate) {
                if (chiEngEntity.getTableNameChi().equals(hmsChiEngEntity.getTableNameChi())) {
                    records.add(hmsChiEngEntity);
                }
            }
        }
        // 构建时间轴数据
        List<TimeLineVo> res = new ArrayList<>();
        Map<String, List<String>> tmpRes = new HashMap<>(); /* 临时时间轴数据 */
        for (HmsChiEngEntity hmsChiEngEntity : records) {
            String tableNameE = hmsChiEngEntity.getTableNameEng();
            List<Map<String, String>> dataByPatientId = xlsxDao.getDataByPatientId(tableNameE, patientId);
            String dateFieldE = hmsChiEngEntity.getEngField();
            for (Map<String, String> map : dataByPatientId) {
                String date = map.get(dateFieldE);
                log.info("格式修改前日期：{}", date);
                date = DateUtil.parseDate(date).toDateStr();
                log.info("格式修改后日期：{}", date);
                List<String> contentList = tmpRes.getOrDefault(date, new ArrayList<>());
                contentList.add(this.getTimeLineContent(hmsChiEngEntity.getTableNameChi(), dateFieldE));
                tmpRes.put(date, contentList);
            }
        }
        for (Map.Entry<String, List<String>> entry : tmpRes.entrySet()) {
            TimeLineVo timeLineVo = new TimeLineVo();
            timeLineVo.setDate(entry.getKey());
            timeLineVo.setContent(entry.getValue());
            res.add(timeLineVo);
        }
        Collections.sort(res);
        return res;
    }

    /**
     * 从表名中抽取时间轴信息
     * @param tableName 中文表名
     * @param field 英文字段名，对出院和入院日期信息做特殊处理
     * @return
     */
    private String getTimeLineContent(String tableName, String field) {
        if (ConstParam.IN_HOSPITAL.equals(field)) {
            return ConstParam.IN_HOSPITAL_MSG;
        }
        if (ConstParam.OUT_HOSPITAL.equals(field)) {
            return ConstParam.OUT_HOSPITAL_MSG;
        }
        if (ConstParam.BASE_INFO_TABLE.equals(tableName)) {
            return ConstParam.BASE_INFO_MSG;
        }
        for (String tableSuffix : ConstParam.TABLE_SUFFIX) {
            if (tableName.contains(tableSuffix)) {
                return tableName.substring(0, tableName.lastIndexOf(tableSuffix));
            }
        }
        throw new HMSException("有时间轴信息不符合规范，请联系开发人员维护");
    }
}
